<?php namespace pft\Prod;
use \pft\Exception\ProductInfoException;
/**
 *产品信息类.
 *获取产品信息.
 * author：孙泽
 * update:cgp
 */
class ProductInfo{
    
    /**
     *产品表ID.
     *@var int
     */
    public $pid;
    
    /**
     *供应商ID.
     *@var int
     */
    public $aid;
    
    /**
     *产品信息键值数组.
     *@var array
     */
    public $p_info;
    
    /**
     *票付通内部接口对象
     *@var object
     */
    public $s;
    
    /**
     *产品类型键值数组
     *@static
     *@var array
     */

    private $db;

    public static $ptype=array("A"=>"景点","B"=>"线路","C"=>"酒店","D"=>"商品","F"=>"套票");
    
    /**
     *构造函数.
     *@param object $s 票付通内部SOAP接口对象
     *@param int $pid 产品ID
     *@param int $aid 供应商ID,直属供应产品按默认值，转供应产品需传
     */
    public function __construct($s, $pid, $db, $aid=0){
        $this->s    = $s;
        $this->pid  = $pid;
        $this->db   = $db;
        $this->aid  = $aid;
        if($aid){
            /*传入上级供应商ID和原始供应商ID比较，直属供应商aid=0*/
            $str="select apply_did from uu_products where id=".$pid;
            $this->db->query($str);
            $this->db->fetch_assoc();
            if($this->db->f("apply_did")==$aid) $this->aid=0;
        }
    }
    
    /**
     *产品价格库存信息查询函数.
     *从接口返回的价格和库存配置xml，得出产品价格库存,存在键值数组中
     *@param object $simplexml simplexml对象
     *@param date $begintime 开始时间
     *@param date $endtime 结束时间
     *@uses ProductInfo::getMinValidTime
     *@uses ProductInfo::getMaxValidTime
     *@return array 
     */
    public function  getDatePrice($simplexml,$beginDate=null,$endDate=null){
        $array=array();
        $sorts=array();
        foreach($simplexml as $xml){    
            $weekdays=$xml->UUweekdays;
            $weekdays=explode(",",$weekdays);
            //平日价，周末价，节日价记录
            $days=(strtotime((string)$xml->UUend_date)-strtotime($xml->UUstart_date))/3600/24;
            $begintime=strtotime($xml->UUstart_date);
            for($i=0;$i<$days+1;$i++){
                $time=$begintime+$i*24*3600;
                $w=date("w",$time);
                $date=date("Y-m-d",$time);
                if($beginDate&&$date<$beginDate) continue;//非指定日期内
                if($endDate&&$date>$endDate) continue;//非指定日期内
                if(!isset($array[$date])){
                    if($xml->UUptype==0){
                        if(in_array($w,$weekdays)){
                            $array[$date] = array(
                                "sprice"  =>(float)$xml->UUn_price,
                                "lprice"  =>(float)$xml->UUl_price,
                                "storage" =>(int)$xml->UUstorage
                            );
                            $sorts[]=$date;
                        }
                    }
                    elseif($xml->UUptype==1){//节假日
                        $array[$date] = array(
                            "sprice"    =>(float)$xml->UUs_price,
                            "lprice"    =>(float)$xml->UUl_price,
                            "uid"       =>(int)$xml->UUid,
                            "storage"   =>(int)$xml->UUstorage
                        );
                        $sorts[]=$date;
                    }
                }elseif($xml->UUptype==1){
                    $array[$date]=array(
                        "sprice"    =>(float)$xml->UUs_price,
                        "lprice"    =>(float)$xml->UUl_price,
                        "uid"       =>(int)$xml->UUid,
                        "storage"   =>(int)$xml->UUstorage
                    );
                }
            }
        }
        array_multisort($sorts,SORT_ASC,SORT_STRING,$array);
        return $array;
    }
    
    /**
     *返回产品最小有效价格日期函数.
     *从传入的时间得出最小有效日期，默认从当前日期加产品预订提前天数，-1表示无有效日期
     *@param date $begintime 启用日期
     *@return date|-1
     */
    public function getMinValidTime($begintime=null,$pid=0){
		if(!$pid)
            $pid=$this->pid;
        $validTime=-1;
        $str="select t.ddays,f.dhour from uu_products p join uu_jq_ticket t on t.pid=p.id left join uu_land_f f on f.pid=p.id where p.id=$pid limit 1";
        $this->db->query($str);
        $p_info=$this->db->fetch_assoc();
        $mintime=date("Y-m-d",time()+3600*24*$p_info['ddays']);
        if($mintime==date("Y-m-d")&&date("H:i:s")>$p_info['dhour']){
            $mintime=date("Y-m-d",strtotime($mintime)+3600*24);
        }
        $begintime=($begintime===null)?$mintime:$begintime;
        $pri_xml=$this->s->get_Dynamic_Price_Merge($pid,"",0,$begintime);
        if($pri_xml==105){
        }elseif(is_numeric($pri_xml)){
            exit($pri_xml);
        }else{
            $pri_xml=simplexml_load_string($pri_xml);
            $array=$this->getDatePrice($pri_xml,$begintime);
            foreach($array as $date=>$price){
                $validTime=$date;
                break;
            }
        }
        return $validTime;
    }
    
    /**
     *返回产品最大有效价格日期函数.
     *从传入的时间得出最大有效日期，默认为空
     *@param date $endtime 截止日期
     *@return date|-1
     */
    public function getMaxValidTime($endtime=""){
        $validTime=-1;
        $begintime=date("Y-m-d");
        /*传入日期小于当天，以当天为准*/
        if($endtime&&$endtime<$begintime) $endtime=$begintime;
        $pri_xml=$this->s->get_Dynamic_Price_Merge($this->pid,"",0,$begintime,$endtime);
        if($pri_xml==105){
        }elseif(is_numeric($pri_xml)){
            exit($pri_xml);
        }else{
            $pri_xml=simplexml_load_string($pri_xml);
            $array=$this->getDatePrice($pri_xml,$begintime,$endtime);
            foreach($array as $date=>$price){
                if($date>$validTime){
                    $validTime=$date;
                }
            }
        }
        return $validTime;
    }
    
    /**
     *返回时间段价格库存信息.
     *@param date $beginDate 开始时间
     *@param date $endDate 介绍时间
     *@return array 
     */
    public function getPeriodPrice($beginDate,$endDate){
        if($endDate<$beginDate){
            $endDate=date("Y-m-d",strtotime($beginDate)+3600*24*100);
        }
        $xml=$this->s->get_Dynamic_Price_Merge($this->pid,"",0);//get_Dynamic_Price_Merge
        $simplexml=simplexml_load_string($xml);
        $array=$this->getDatePrice($simplexml,$beginDate,$endDate);
        return $array;
    }
    
    /**
     *返回产品信息.
     *@return array 
     */
    public function pInfo($pid = 0){
//        $time_start = microtime_float();
        if($pid==$this->pid && !empty($this->p_info)) {
            return $this->p_info;
        }
        if(!$pid) {
            $pid = $this->pid;
        }
       /*$sql_ticket = <<<SQL
        SELECT p.id as pid,p.apply_limit,p.salerid,p.p_status,p.apply_did,
        t.id as tid,t.tprice,t.pay,t.title as ttitle,t.delaydays,t.landid,
        t.ddays,t.buy_limit_low,t.buy_limit_up,t.status,t.storage_open,
        t.storage,t.getaddr
        FROM uu_products p LEFT JOIN uu_jq_ticket t ON p.id=t.pid
        WHERE p.id={$pid} LIMIT 1
SQL;
        $this->db->query($sql_ticket);
        $pData = $this->db->fetch_assoc();

        $lid = $pData['landid'];
        $sql_land = <<<SQL
        SELECT l.id as lid,l.title as ltitle,l.fax,l.attribute,
        l.p_type,l.jdjj,l.jqts,l.imgpath
        FROM uu_land l
        WHERE l.id={$lid} LIMIT 1
SQL;
        $this->db->query($sql_land);
        $landData = $this->db->fetch_assoc();
        $ext_sql = "SELECT lid,dhour,mdays,mhour,startplace,endplace,rdays," .
            "ass_station,series_model,tourist_info,confirm_sms,manual_verify,".
            "v_mobile_support FROM uu_land_f WHERE pid={$this->pid} LIMIT 1";
        $this->db->query($ext_sql);
        $extData = $this->db->fetch_assoc();

        $this->p_info = array_merge($pData, $landData, $extData);
        $this->p_info['sapply_did'] = $this->aid==0 ?
            $this->p_info['apply_did'] : $this->aid;*/

       $str="select p.id as pid,p.apply_limit,p.salerid,p.p_status,".
            "p.apply_did,l.id as lid,l.title as ltitle,l.fax,l.attribute,".
            "l.p_type,l.jdjj,l.jqts,l.imgpath,t.id as tid,t.tprice,t.pay,".
            "t.title as ttitle,t.delaydays,t.ddays,t.buy_limit_low,".
            "t.buy_limit_up,t.status,t.storage_open,t.storage,t.getaddr,".
            "f.dhour,f.series_model,f.mdays from uu_products p ".
            "left join uu_jq_ticket t on p.id=t.pid ".
            "left join uu_land l on p.contact_id=l.id ".
            "left join uu_land_f f on p.id=f.pid ".
            "where p.id=".$pid." limit 1";
        $this->db->query($str);
        $this->p_info = $this->db->fetch_assoc();
        $this->p_info['sapply_did'] = $this->aid==0 ?
                                    $this->p_info['apply_did'] : $this->aid;
//        return $this->p_info;
//        $time_end = microtime_float();
//        $time = $time_end - $time_start;
//        echo 'time used:' ,$time;
        return $this->p_info;
    }
    
    /**
     *返回产品价格.
     *@param int $did 分销商ID
     *@param date $date 预订日期
     *@param int $sale 是否零售
     *@return int 
     */
    public function tPrice($did,$date,$sale=0, $pid=0){
        $date = substr($date, 0, 10);
        if($sale==1)
            return $this->uPrice($date, $pid);
        else
            return $this->jsPrice($did, $date, $pid);
    }
    
    /**
     *返回产品分销价.
     *@param int $did 分销商ID
     *@param date $date 预订日期
     *@return int 
     */
    public function jsPrice($did, $date, $pid=0){
        if(!$pid) {
            $pid = $this->pid;
        }
        $jsprice=$this->s->get_Dynamic_Price_Merge($pid, $date, 1);
        if($jsprice==-1) {
            throw new ProductInfoException("产品{$pid} {$date} 结算价未设置");
        }
        $dprice=$this->dprice($did, $pid);
        $jsprice=($dprice+$jsprice);
//        echo '<br/>+++++++++'.$pid.'='.$jsprice.'+++++<br/>';
        return $jsprice;
    }
    
    /**
     *返回产品零售价.
     *@param int $did 分销商ID
     *@param date $date 预订日期
     *@return int 
     */
    public function uPrice($date, $pid=0){
        if(!$pid) {
            $pid = $this->pid;
        }
        $uprice=$this->s->get_Dynamic_Price_Merge($pid,$date,1,'','',1);
        if($uprice==-1)
            throw new \ProductInfoException("产品{$pid} {$date} 零售价未设置");
        return $uprice;
    }
    
    /**
     *返回产品零售价.
     *@param int $did 分销商ID
     *@param date $date 预订日期
     *@return int 
     */
    public function dprice($did, $pid=0){
        $pid = !$pid ? $this->pid : $pid;
        $aid=$this->aid;
        $str="select dprice from uu_priceset  where tid=$pid and pid=$did and aid=$aid";
        $this->db->query($str);
        $this->db->fetch_assoc();
        $dprice=abs($this->db->f('dprice'));
        if($aid!=0){//二手供应产品
            $str="select aids from pft_p_apply_evolute where pid=$pid and fid=$did and sid=$aid";
            $this->db->query($str);
            $this->db->fetch_assoc();
            $aids=$this->db->f("aids");
            if ($aids) {
                $str="select * from uu_priceset where pid in ($aids)";
                $this->db->query($str);
                while($row=$this->db->fetch_assoc()){
                    $dprices2[$row['tid']."_".$row['pid']."_".$row['aid']]=$row['dprice'];
                }
                $aids=explode(",",$aids);
                $aids[0]=0;
                $count=count($aids);
                for($i=1;$i<$count;$i++){
                    $dprice=$dprice+$dprices2[$pid."_".$aids[$i]."_".$aids[$i-1]];
                }
            }
        }
        return $dprice;
    }
    
    /**
     *返回产品指定日期库存.
     *@param date $date 预订日期
     *@return int  
     */
    public function dayStorage($date){
        $storage=-1;
        $p_info=$this->pInfo();
        $pstorage=$this->s->get_Dynamic_Price_Merge($p_info['pid'],substr($date,0,10),1,"","",0,1);
        $pstorage=explode(",",$pstorage);
        $pstorage=$pstorage[1];//设置的日库存
        if($pstorage!=-1){
            $storageXml=$this->s->Dynamic_Storage_Check($p_info['tid'],1,$date);
            $storageXml=simplexml_load_string($storageXml);
            $storageXml=(string)$storageXml->Rec->UUXstr;
            $dayStorage=explode("|",$storageXml);
            $dayStorage=$dayStorage[1];//使用的日库存
            $storage=$pstorage-$dayStorage;
        }
        if($p_info['storage']!=-1){
            $storageXml=$this->s->Dynamic_Storage_Check($p_info['tid'],2,NUll,$p_info['storage_open']);
            $storageXml=simplexml_load_string($storageXml);
            $useStorage=$storageXml->Rec->UUXstr;
            $totalStorage=$p_info['storage']-$useStorage;//剩余总库存
            if(($totalStorage<$storage&&$storage>0)||$storage==-1) $storage=$totalStorage;
        }
        if($storage==-1) $storage="不限";
        return $storage;
    }
    
    /**
     *产品供应查看函数.
     *查看产品是否供应供应给该分销商
     *@param int $did 分销商ID
     *return bool
     */
    public function supply($did){
        $str="select apply_did from uu_products where id=".$this->pid." limit 1";
        $this->db->query($str);
        $this->db->fetch_assoc();
        $apply_did=$this->db->f("apply_did");
        //自身供应的产品
        if($apply_did==$did) return true;
        $str="select pids from pft_product_sale_list where fid=$did and aid=$apply_did";
        $this->db->query($str);
        if($this->db->fetch_assoc()){
            $pids=$this->db->f("pids");
            if($pids=="A") return true;
            if(in_array($this->pid,explode(",",$pids))) return true;
        }
        //二手转供应的产品
        $str="select id from pft_p_apply_evolute where pid=".$this->pid." and sid=".$this->aid." and status=0";
        $this->db->query($str);
        if($this->db->fetch_assoc()) return true;
        
        return false;
    }
    
    /**
     *产品供应是否在售.
     *查看产品是否在售，非在售产品抛出异常
     *@throws ProductInfoException
     */
    public function saleCheck(){
        $p_info=$this->pInfo();
        $pid=$p_info['pid'];
        if($p_info['apply_limit']!=1)
            throw new \ProductInfoException("产品 $pid 未通过审核");
        if($p_info['p_status']!=0&&$p_info['p_status']!=3&&$p_info['p_status']!=4&&$p_info['p_status']!=5) 
            throw new \ProductInfoException("无发分销该产品");
    }
}
?>